﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sakura.Games.StgFramework
{
	/// <summary>
	/// 表示一个点。
	/// </summary>
	public struct Point : IEquatable<Point>
	{
		/// <summary>
		/// 获取或设置该点的 X 坐标的值。
		/// </summary>
		public int X
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置该点的 Y 坐标的值。
		/// </summary>
		public int Y
		{
			get;
			set;
		}

		/// <summary>
		/// 初始化一个新的点。
		/// </summary>
		/// <param name="x">新点的 X 坐标的值。</param>
		/// <param name="y">新点的 Y 坐标的值。</param>
		public Point(int x, int y) : this()
		{
			this.X = x;
			this.Y = y;
		}

		/// <summary>
		/// 表示原点坐标。原点坐标的两个方向位置均为零。
		/// </summary>
		public static Point Origin
		{
			get
			{
				return new Point(0, 0);
			}
		}

		/// <summary>
		/// 判断该点是否和另一个点相等。
		/// </summary>
		/// <param name="other">要判断的另一个点。</param>
		/// <returns>如果该点和另一个点相等，返回 <c>true</c>；否则返回 <c>false</c>。</returns>
		public bool Equals(Point other)
		{
			return this.X == other.X && this.Y == other.Y;
		}

		/// <summary>
		/// 判断该对象是否和另一个对象相等。
		/// </summary>
		/// <param name="obj">要判断的另一个对象。</param>
		/// <returns>如果该对象和另一个对象相等，返回 <c>true</c>；否则返回 <c>false</c>。</returns>
		public override bool Equals(object obj)
		{
			if (obj == null || obj.GetType() != typeof(Point))
			{
				return false;
			}

			return this.Equals((Point)obj);
		}

		/// <summary>
		/// 返回该对象的哈希代码。
		/// </summary>
		/// <returns>该对象的哈希代码。</returns>
		public override int GetHashCode()
		{
			return this.X.GetHashCode() ^ this.Y.GetHashCode();
		}

		/// <summary>
		/// 判断两个点是否相等。
		/// </summary>
		/// <param name="p1">要判断的第一个点。</param>
		/// <param name="p2">要判断的第二个点。</param>
		/// <returns>如果两个点相等，返回 <c>true</c>；否则返回 <c>false</c>。</returns>
		public static bool operator ==(Point p1, Point p2)
		{
			return p1.Equals(p2);
		}

		/// <summary>
		/// 判断两个点是否不相等。
		/// </summary>
		/// <param name="p1">要判断的第一个点。</param>
		/// <param name="p2">要判断的第二个点。</param>
		/// <returns>如果两个点不相等，返回 <c>true</c>；否则返回 <c>false</c>。</returns>
		public static bool operator !=(Point p1, Point p2)
		{
			return !p1.Equals(p2);
		}
	}
}
